home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / tptc16.zip / FMAP.PAS < prev    next >
Pascal/Delphi Source File  |  1993-01-04  |  6KB  |  302 lines

  1.  
  2. (*
  3.  * fmap - find symbols related to an address in a .MAP load
  4.  *        map generated by LINK or TMAP
  5.  *
  6.  * S.H.Smith, 27-jan-86
  7.  *
  8.  *)
  9.  
  10. {$g512,p512,c-}
  11.  
  12.  
  13. const
  14.    version = 'FMAP 1.0 (1/26/87 SHS)';
  15.  
  16. type
  17.    anystring = string[80];
  18.  
  19. var
  20.    line:    anystring;
  21.    fd:      text[10240];
  22.    target:  anystring;
  23.    mapname: anystring;
  24.  
  25.  
  26. procedure abort_check;
  27. begin
  28.    if keypressed then
  29.    begin
  30.       writeln('aborted');
  31.       halt;
  32.    end;
  33. end;
  34.  
  35.  
  36. (* ----------------------------------------------------------------- *)
  37. procedure parse_segments;
  38. begin
  39.    writeln('Segments');
  40.    repeat
  41.       readln(fd,line);
  42.    until length(line) < 20;
  43. end;
  44.  
  45.  
  46. (* ----------------------------------------------------------------- *)
  47. procedure parse_by_name;
  48. begin
  49.    writeln('Names');
  50.    readln(fd,line);
  51.  
  52.    repeat
  53.       readln(fd,line);
  54.       abort_check;
  55.    until length(line) < 17;
  56. end;
  57.  
  58.  
  59. (* ----------------------------------------------------------------- *)
  60. procedure parse_by_value;
  61. var
  62.    pr:      anystring;
  63.    ad:      anystring;
  64.    ppr:     anystring;
  65.    pad:     anystring;
  66.    pline:   anystring;
  67.  
  68. begin
  69.    writeln('Values');
  70.    readln(fd,line);
  71.    pad := '0000';
  72.    ppr := '';
  73.  
  74.    repeat
  75.       ad := copy(line,7,4);
  76.       pr := copy(line,18,99);
  77.       if (ppr <> '') and (target >= pad) and (target < ad) then
  78.          writeln(pad,'-',ad,' ',pline);
  79.  
  80.       pad := ad;
  81.       ppr := pr;
  82.       pline := line;
  83.  
  84.       readln(fd,line);
  85.       abort_check;
  86.    until length(line) < 17;
  87. end;
  88.  
  89.  
  90. procedure output_lines(name: anystring; first, last: integer);
  91. var
  92.    fd: text[1024];
  93.    n:  integer;
  94.    b:  anystring;
  95.  
  96. begin
  97.    writeln('Output lines ',first,'-',last,' from ',name);
  98.    assign(fd,name);
  99. {$i-}
  100.    reset(fd);
  101. {$i+}
  102.    if ioresult <> 0 then
  103.    begin
  104.       writeln('can''t find source file: ',name);
  105.       writeln('need lines ',first,'-',last);
  106.       halt;
  107.    end;
  108.  
  109. {$i-}
  110.    for n := 1 to first-1 do
  111.       readln(fd,b);
  112.  
  113.    for n := first to last+1 do
  114.    begin
  115.       writeln(n:6,'| ',b);
  116.       readln(fd,b);
  117.       abort_check;
  118.    end;
  119. {$i+}
  120.  
  121.    close(fd);
  122. end;
  123.  
  124.  
  125. (* ----------------------------------------------------------------- *)
  126. var
  127.    name:    anystring;
  128.    ln:      integer;
  129.    ad:      anystring;
  130.    pln:     integer;
  131.    pad:     anystring;
  132.    first:   boolean;
  133.  
  134.    procedure check_match;
  135.    begin
  136.       writeln('   check match, ',pad,'-',ad,'  lines ',pln,'-',ln);
  137.  
  138.       if (pln <> 0) and (target >= pad) and (target < ad) then
  139.       begin
  140.          if first then
  141.          begin
  142.             writeln;
  143.             writeln('==============================');
  144.             writeln(name);
  145.             first := false;
  146.          end;
  147.  
  148.          if (ln-pln) < 20 then
  149.          begin
  150.             writeln('---------');
  151.             writeln(pad,'-',ad);
  152.             output_lines(name,pln,ln);
  153.          end
  154.          else
  155.          begin
  156.             writeln('---------');
  157.             writeln(pad,'-',ad,'  lines ',pln,'-',ln);
  158.          end;
  159.       end;
  160.    end;
  161.  
  162. procedure parse_line_numbers;
  163. var
  164.    i:       integer;
  165.    code:    integer;
  166.    buf:     anystring;
  167.  
  168. begin
  169.    writeln('Line numbers: ',line);
  170.  
  171.    i := pos('(',line) + 1;
  172.    name := '';
  173.    while line[i] <> ')' do
  174.    begin
  175.       name := name + line[i];
  176.       i := i + 1;
  177.    end;
  178.  
  179.    readln(fd,line);
  180.    writeln('name=[',name,']');
  181.  
  182.    pln := 0;
  183.    pad := '0000';
  184.    first := true;
  185.  
  186.    repeat
  187.       abort_check;
  188.  
  189.       while length(line) > 6 do
  190.       begin
  191.  
  192.          {extract the line number}
  193.          buf := copy(line,1,5);
  194.          while copy(buf,1,1) = ' ' do
  195.             delete(buf,1,1);
  196.          val(buf,ln,code);
  197.  
  198.          {extract the code address}
  199.          ad := copy(line,12,4);
  200.  
  201.          {remove the processed part of the line}
  202.          delete(line,1,17);
  203.  
  204.          {if target is between two lines, then print it out}
  205.          check_match;
  206.  
  207.          pad := ad;
  208.          pln := ln;
  209.       end;
  210.  
  211.       readln(fd,line);
  212.    until length(line) < 6;
  213.  
  214.    check_match;   {process the last line}
  215. end;
  216.  
  217.  
  218. (* ----------------------------------------------------------------- *)
  219. procedure parse_others;
  220. begin
  221.    writeln('Other: ',line);
  222.    readln(fd,line);
  223. end;
  224.  
  225.  
  226. (* ----------------------------------------------------------------- *)
  227. procedure parse_mapfile;
  228. begin
  229.    writeln('Scanning mapfile ',mapname);
  230.    writeln('for address ',target,':');
  231.    writeln;
  232.  
  233.    readln(fd,line);
  234.  
  235.    while not eof(fd) do
  236.    begin
  237.       if copy(line,1,30) = ' Start  Stop   Length Name    ' then
  238.          parse_segments
  239.       else
  240.       if copy(line,1,30) = '  Address         Publics by N' then
  241.          parse_by_name
  242.       else
  243.       if copy(line,1,30) = '  Address         Publics by V' then
  244.          parse_by_value
  245.       else
  246.       if copy(line,1,17) = 'Line numbers for ' then
  247.          parse_line_numbers
  248.       else
  249.          parse_others;
  250.  
  251.       abort_check;
  252.    end;
  253.  
  254.    close(fd);
  255. end;
  256.  
  257.  
  258. (* ----------------------------------------------------------------- *)
  259. var
  260.    i: integer;
  261.  
  262. begin
  263.    writeln;
  264.    writeln(version);
  265.    writeln;
  266.  
  267.    if paramcount <> 2 then
  268.    begin
  269.       writeln('Usage: fmap MAPFILE TARGET_ADDRESS');
  270.       writeln('Finds references to TARGET_ADDRESS in MAPFILE.');
  271.       halt(1);
  272.    end;
  273.  
  274.    mapname := paramstr(1);
  275.    if pos('.',mapname) = 0 then
  276.       mapname := mapname + '.MAP';
  277.  
  278.    assign(fd,mapname);
  279. {$i-}
  280.    reset(fd);
  281. {$i+}
  282.    if ioresult <> 0 then
  283.    begin
  284.       writeln('can''t open mapfile: ',mapname);
  285.       halt;
  286.    end;
  287.  
  288.    target := paramstr(2);
  289.    for i := 1 to length(target) do
  290.       target[i] := upcase(target[i]);
  291.  
  292.    if length(target) <> 4 then
  293.    begin
  294.       writeln('TARGET_ADDRESS must be 4 hex digits');
  295.       halt;
  296.    end;
  297.  
  298.    parse_mapfile;
  299.    writeln;
  300. end.
  301.  
  302.